package com.iot.iotplus.service.impl;

import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.iot.iotplus.VO.DeviceVO;
import com.iot.iotplus.VO.ProductCountVO;
import com.iot.iotplus.base.CommonPage;
import com.iot.iotplus.base.Result;
import com.iot.iotplus.entity.*;
import com.iot.iotplus.mapper.DeviceMapper;
import com.iot.iotplus.mapper.DeviceTopicMapper;
import com.iot.iotplus.mapper.DeviceTypeMapper;
import com.iot.iotplus.mapper.MessageMapper;
import com.iot.iotplus.service.DeviceService;
import com.iot.iotplus.utils.ResultUtil;
import com.iot.iotplus.utils.SnowflakeIdGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class DeviceServiceImpl implements DeviceService {

    @Autowired
    private DeviceMapper deviceMapper;
    @Autowired
    private DeviceTypeMapper deviceTypeMapper;
    @Autowired
    private DeviceTopicMapper deviceTopicMapper;
    @Autowired
    private MessageMapper messageMapper;
    @Override
    public Result<CommonPage<Device>> listDevice(String tenantId,String productId,int pageNum, int pageSize) {
        Page<Device> page = new Page<>(pageNum, pageSize);
        QueryWrapper<Device> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("tenant_id",tenantId).eq("product_id",productId).eq("deleted",0);
        IPage<Device> deviceIPage = deviceMapper.selectPage(page, queryWrapper); // 调用 selectPage 方法
        List<Device> deviceList = deviceIPage.getRecords();
        long total = deviceIPage.getTotal();
        Integer totalPage = Math.toIntExact(deviceIPage.getPages());
        return ResultUtil.success(new CommonPage<>(pageNum,pageSize,totalPage,total,deviceList));
    }
    @Override
    public Result<CommonPage<Device>> listDeviceByProduct(String tenantId,int pageNum, int pageSize) {
        Page<Device> page = new Page<>(pageNum, pageSize);
        QueryWrapper<Device> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("tenant_id",tenantId).eq("deleted",0);
        IPage<Device> deviceIPage = deviceMapper.selectPage(page, queryWrapper); // 调用 selectPage 方法
        List<Device> deviceList = deviceIPage.getRecords();
        long total = deviceIPage.getTotal();
        Integer totalPage = Math.toIntExact(deviceIPage.getPages());
        return ResultUtil.success(new CommonPage<>(pageNum,pageSize,totalPage,total,deviceList));
    }

    public Result<DeviceVO> selectOneDevice(String id) {
        Device device = deviceMapper.selectById(id);
        String deviceKey = device.getDeviceKey();
        QueryWrapper<DeviceTopic> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("device_key",deviceKey);
        List<DeviceTopic> topics = deviceTopicMapper.selectList(queryWrapper);
        return ResultUtil.success(new DeviceVO(device,topics));
    }

    @Override
    @Transactional
    public Result deleteById(String id) {
        try{
            Optional.of(id);
        }catch (NullPointerException e){
            return ResultUtil.validateFailed();
        }
        int i = deviceMapper.deleteById(id);
        return ResultUtil.success(i);
    }

    @Override
    public Result<List<DeviceType>> listDes() {
        return ResultUtil.success(deviceTypeMapper.selectList(null));
    }

    @Override
    @Transactional
    public Result<Integer> addDevice(Device device) {
        String deviceId = SnowflakeIdGenerator.getSnowflakeId().toString();
        String deviceKey= "device_" + deviceId;
        String deviceSecret = SecureUtil.md5(device.getName());
        device.setId(deviceId);
        device.setDeviceKey(deviceKey);
        device.setDeviceSecret(deviceSecret);
        device.setCreateTime(new Date());
        device.setUpdateTime(new Date());
        DeviceTopic subscribe = new DeviceTopic(SnowflakeIdGenerator.getSnowflakeId().toString(), "/smart/device/data/" + deviceKey, new Date(), new Date(), 0, deviceKey);
        DeviceTopic send = new DeviceTopic(SnowflakeIdGenerator.getSnowflakeId().toString().toString(), "/smart/device/ctrl/" + deviceKey, new Date(), new Date(), 0, deviceKey);
        int i1 = deviceMapper.insert(device);
        int i2 = deviceTopicMapper.insert(subscribe);
        int i3 = deviceTopicMapper.insert(send);
        if (i1 != 1 || i2!=1 || i3!=1) {
            return ResultUtil.failed();
        }
        return ResultUtil.success(i1+i2+i3);
    }

    //查询所有设备、激活设备、当前在线设备
    @Override
    public Result<?> countDevice(String tenantId) {
        QueryWrapper<Device> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("tenant_id",tenantId).eq("deleted",0);
        Integer totalDevices = Math.toIntExact(deviceMapper.selectCount(queryWrapper));

        // 假设设备状态为"activated"表示已激活
        queryWrapper.eq("active",2);
        Integer activatedDevices = Math.toIntExact(deviceMapper.selectCount(queryWrapper));


        // 假设设备有一个字段叫做"online_status"，值为"true"表示在线
        Integer onlineDevices =deviceMapper.countOnlineDevice(tenantId);
        ArrayList<Integer> array = new ArrayList<>();
        array.add(totalDevices);
        array.add(activatedDevices);
        array.add(onlineDevices);
        return ResultUtil.success(array);
    }

    @Override
    public Result<Integer> deviceActivate(String deviceKey) {
        LambdaQueryWrapper<Device> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Device::getDeviceKey,deviceKey);
        Device device = deviceMapper.selectOne(wrapper);
        wrapper.eq(Device::getActive,1);
        device.setActive(2);
        Integer i = deviceMapper.update(device, wrapper);
        return ResultUtil.success(i);
    }

    @Override
    public Result<List<ProductCountVO>> countProds(String tenantId) {
        List<ProductCountVO> productCountVOS = deviceMapper.productCount(tenantId);
        Result<List<ProductCountVO>> success = ResultUtil.success(productCountVOS);
        return  success;
    }

    @Override
    public Result<?> getDeviceType(String typeId) {
        if (typeId == null){
            return ResultUtil.failed();
        }
        DeviceType deviceType = deviceTypeMapper.selectById(typeId);
        return ResultUtil.success(deviceType);
    }

    @Override
    public Result<?> getUpLinkData(String product, String device, String tenant,Integer pageNum,Integer pageSize) {
        if (product == null || device == null || tenant == null)
            return ResultUtil.failed();
        IPage<Message> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<Message> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Message::getProductKey,product);
        wrapper.eq(Message::getDevice,device);
        wrapper.eq(Message::getTenantId,tenant);
        IPage<Message> messageIPage = messageMapper.selectPage(page, wrapper);
        if (messageIPage.getRecords().isEmpty())
            return ResultUtil.failed();
        CommonPage<Message> commonPage = new CommonPage<>(
                (int) messageIPage.getCurrent(),
                (int) messageIPage.getSize(),
                (int) messageIPage.getPages(),
                messageIPage.getTotal(),
                messageIPage.getRecords());
        return ResultUtil.success(commonPage);
    }

}
